<template>
  <!-- <bread-crumb></bread-crumb>
  <x-card
    :message="message_card"
    :width="98"
    :height="height"
    style="margin: 20px 20px"
  > -->
  <!-- 搜索以及操作 -->
  <!-- 自定义组件 -->
  <x-search>
    <!-- 搜索的一系列东西 -->
    <template #search>
      <p>
        角色名称
        <a-input
          v-model:value="role_name"
          placeholder="请输入角色名称"
          style="width: 150px"
        />
      </p>
      <p style="margin-left: 10px">
        角色编码
        <a-input
          v-model:value="role_code"
          placeholder="请输入角色编码"
          style="width: 150px"
        />
      </p>
      <a-button type="primary" style="margin-left: 10px" @click="but_search"
        >搜索</a-button
      >
      <a-button style="margin-left: 10px" @click="reset_search">重置</a-button>
    </template>
    <!-- 操作的一系列东西 -->
    <template #operate>
      <a-button
        type="primary"
        style="margin-left: 10px"
        @click="showModal_add"
        v-checkpermission:foo.bar="'system_role_add'"
        ><template #icon><plus-outlined style="margin-right: 0" /></template
        >新增角色</a-button
      >
    </template>
  </x-search>
  <!-- 谈话框--添加角色 -->
  <a-modal v-model:open="open_add" title="新增角色" @ok="handleOk">
    <a-form
      ref="formRef"
      :model="formState"
      :rules="rules"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
      <a-form-item label="角色名" name="name">
        <a-input v-model:value="formState.name" placeholder="请输入角色名" />
      </a-form-item>
      <a-form-item label="角色编码" name="rolecode">
        <a-input
          v-model:value="formState.rolecode"
          placeholder="请输入角色编码"
        />
      </a-form-item>
      <a-form-item label="角色描述" name="description">
        <a-input
          v-model:value="formState.description"
          placeholder="请输入角色描述"
        />
      </a-form-item>
    </a-form>
  </a-modal>
  <!-- 搜索下面的表格 -->
  <a-table
    :dataSource="dataSource"
    :columns="columns"
    :loading="loading"
    :pagination="{
      pageSize: state.pageSize,
      total: state.total,
      current: state.current,
      showSizeChanger: true, // 显示每页条数选择器
      pageSizeOptions: ['10', '20', '50'], // 自定义每页条数选项
      showTotal: (total) => `共 ${total} 条`, // 显示总条数
    }"
    @change="
      (pagination) => {
        console.log(pagination);
        state.pageSize = pagination.pageSize;
        state.total = pagination.total;
        state.current = pagination.current;
        role_list();
      }
    "
    :scroll="{ y: 600 }"
    v-checkpermission:foo.bar="'system_role_list'"
  >
    <!-- :columns="columns" :data-source="data" @resizeColumn="handleResizeColumn" -->
    <!-- 头部表头默认显示，不需要操作 -->
    <!-- <template #headerCell="{ column }"></template> -->
    <!-- 身体-表格中的列表 -->
    <!-- <template #bodyCell="{ column, record }"> -->
    <template #bodyCell="{ column, record }">
      <template v-if="column.key === 'role_name'">
        <!-- {{ record }} -->
        <span>
          <!-- hhh -->
          <button
            style="
              border: none;
              background-color: #f4f4f5;
              border-radius: 5px;
              color: #92969b;
            "
          >
            {{ record.role_name }}
          </button>
          <!-- <p>{{ record.role_name }}</p> -->
        </span>
      </template>
      <template v-else-if="column.key === 'action'">
        <a-space>
          <!-- 查看权限详情 -->
          <a-tooltip title="查看权限详情" placement="top">
            <a-button
              type="text"
              size="small"
              @click="per_view(record.id)"
              v-checkpermission:foo.bar="'system_permiss_edit'"
            >
              <template #icon>
                <EyeOutlined />
                <!-- <EditOutlined style="color: #1890ff" /> -->
              </template>
            </a-button>
          </a-tooltip>

          <!-- 编辑按钮 -->
          <a-tooltip title="编辑" placement="top">
            <a-button
              type="text"
              size="small"
              @click="showModal_edit(record.id)"
              v-checkpermission:foo.bar="'system_role_edit'"
            >
              <template #icon>
                <EditOutlined style="color: #1890ff" />
              </template>
            </a-button>
          </a-tooltip>

          <!-- 权限设置按钮 -->
          <a-tooltip title="权限设置" placement="top">
            <a-button
              type="text"
              size="small"
              @click="permise_set(record)"
              v-checkpermission:foo.bar="'system_role_set'"
            >
              <template #icon>
                <LockOutlined style="color: #722ed1" />
              </template>
            </a-button>
          </a-tooltip>

          <!-- 状态切换按钮 -->
          <a-tooltip
            :title="record.state === 0 ? '禁用' : '启用'"
            placement="top"
          >
            <a-button
              type="text"
              size="small"
              danger
              @click="
                record.state === 0
                  ? del_user_f(record.id)
                  : start_user_f(record.id)
              "
              v-checkpermission:foo.bar="'system_role_delete'"
            >
              <template #icon>
                <DeleteOutlined
                  :style="{ color: record.state === 0 ? '#ff4d4f' : '#52c41a' }"
                />
              </template>
            </a-button>
          </a-tooltip>

          <!-- 真删除按钮（仅当状态为1时显示） -->
          <a-tooltip v-if="record.state === 1" title="删除" placement="top">
            <a-button
              type="text"
              size="small"
              danger
              @click="del_user_t(record.id)"
              v-checkpermission:foo.bar="'system_role_delete'"
            >
              <template #icon>
                <DeleteOutlined style="color: #cf1322" />
              </template>
            </a-button>
          </a-tooltip>
        </a-space>
      </template>
    </template>
  </a-table>
  <!-- 谈话框--编辑角色 -->
  <a-modal v-model:open="open_edit" title="修改角色" @ok="handleOk_edit">
    <a-form
      ref="formRef_edit"
      :model="formState_edit"
      :rules="rules"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
      <a-form-item label="角色名" name="name">
        <a-input v-model:value="formState_edit.name" />
      </a-form-item>
      <a-form-item label="角色描述" name="description">
        <a-input v-model:value="formState_edit.description" />
      </a-form-item>
      <a-form-item label="角色编码" name="rolecode">
        <a-input v-model:value="formState_edit.rolecode" />
      </a-form-item>
    </a-form>
  </a-modal>
  <!-- 对话框--角色权限设置 -->
  <a-modal v-model:open="open_set" :title="set_permis_title" @ok="handleOk_set">
    <a-tree
      v-model:checkedKeys="value_set"
      checkable
      :tree-data="options"
      :field-names="{ key: 'value', title: 'label' }"
      :selectable="false"
      :defaultExpandAll="true"
      show-line
      style="width: 100%"
      placeholder="请选择权限"
    />
  </a-modal>
  <!-- 角色的权限详情 -->
  <!-- 抽屉组件 -->
  <a-drawer
    :title="`${roleData.roleName} 权限详情`"
    :width="600"
    :visible="visible"
    @close="onClose"
  >
    <!-- 1. 角色基本信息 -->
    <a-descriptions bordered :column="2">
      <a-descriptions-item label="角色ID">{{
        roleData.roleId
      }}</a-descriptions-item>
      <a-descriptions-item label="角色名称">{{
        roleData.roleName
      }}</a-descriptions-item>
      <a-descriptions-item label="权限总数">{{
        roleData.total
      }}</a-descriptions-item>
      <a-descriptions-item label="最后更新">
        {{ new Date(roleData.updatedAt).toLocaleString() }}
      </a-descriptions-item>
    </a-descriptions>

    <!-- 2. 权限分级列表 -->
    <!-- 该权限的类型：0 菜单；1 按钮；2 页面 -->
    <a-divider orientation="left">菜单级权限</a-divider>
    <a-list :data-source="roleData.permissions.level0">
      <template #renderItem="{ item }">
        <a-list-item>
          <a-list-item-meta :description="`组件: ${item.component}`">
            <template #title>
              <a-space>
                <AppstoreOutlined v-if="item.icon === 'AppstoreOutlined'" />
                <span>{{ item.name }}</span>
              </a-space>
            </template>
            <template #avatar>
              <a-typography-text type="secondary"
                >#{{ item.id }}</a-typography-text
              >
            </template>
          </a-list-item-meta>
        </a-list-item>
      </template>
    </a-list>

    <!-- 三级权限（如果有数据才显示） -->
    <template v-if="roleData.permissions.level2.length > 0">
      <a-divider orientation="left">页面级权限</a-divider>
      <a-list :data-source="roleData.permissions.level2">
        <template #renderItem="{ item }">
          <a-list-item>
            <a-list-item-meta :description="`组件: ${item.component}`">
              <template #title>
                <a-space>
                  <AppstoreOutlined v-if="item.icon === 'AppstoreOutlined'" />
                  <span>{{ item.name }}</span>
                </a-space>
              </template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
    </template>

    <template v-if="roleData.permissions.level1.length > 0">
      <a-divider orientation="left">按钮级权限</a-divider>
      <a-list :data-source="roleData.permissions.level1">
        <template #renderItem="{ item }">
          <a-list-item>
            <a-list-item-meta :description="`组件: ${item.component}`">
              <template #title>
                <a-space>
                  <AppstoreOutlined v-if="item.icon === 'AppstoreOutlined'" />
                  <span>{{ item.name }}</span>
                </a-space>
              </template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
    </template>
  </a-drawer>
  <!-- </x-card> -->
</template>

<script lang="ts" setup>
import XSearch from "./XSearch.vue";
import { ref, reactive, toRaw, onMounted, createVNode } from "vue";
import http from "../routerutils/http";
import { message, Modal, Cascader } from "ant-design-vue";
// 对话提示
import {
  EditOutlined,
  LockOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
  PlusOutlined,
  EyeOutlined
} from "@ant-design/icons-vue";
// 表单验证
import type { Rule } from "ant-design-vue/es/form";
import type { UnwrapRef } from "vue";
import type { CascaderProps } from "ant-design-vue";
import { useStore } from "vuex";
import dayjs from "dayjs";
const store = useStore();
const userPermiss_vuex = store.state.userPermiss;
// 创建一个自定义指令，来统一处理权限存在与否
const vCheckpermission = {
  mounted: (el: any, binding: any) => {
    if (!userPermiss_vuex.includes(binding.value)) {
      // 移除元素
      el.parentNode?.removeChild(el);
    }
    console.log(el, binding);
    // el.classList.add("is-highlight");
  },
};

// 新增：角色的权限详情
// 定义类型
interface Permission {
  id: number;
  name: string;
  component: string;
  icon: string;
}

interface RolePermissions {
  roleId: number;
  roleName: string;
  permissions: {
    level0: Permission[];
    level1: Permission[];
    level2: Permission[];
    level3: Permission[];
  };
  total: number;
  updatedAt: string;
}

const roleData = ref<RolePermissions>({
  roleId: 0,
  roleName: "",
  permissions: {
    level0: [],
    level1: [],
    level2: [],
    level3: [],
  },
  total: 0,
  updatedAt: "",
});
// 抽屉控制
const visible = ref(false);
const showDrawer = () => {
  visible.value = true;
};
const onClose = () => {
  visible.value = false;
};

// x-card组件中的属性值
const message_card = ref<string>("");
const height = ref<string>("850px");
// 1. 搜索相关的操作数据
const role_name = ref<string>("");
const role_code = ref<string>("");
// 重置按钮的方法
const reset_search = () => {
  role_name.value = "";
  role_code.value = "";
  state.current = 1
  role_list();
};
// 搜索按钮的方法
const but_search = () => {
  role_list();
};
// 2. 新增角色按钮的相关操作
// 添加角色接口
const add_role = async () => {
  try {
    const response = await http.post("/api/roles/addrole", {
      name: formState.name,
      description: formState.description,
      rolecode: formState.rolecode,
    });
    console.log("添加角色：", response);
    const msg = response.data.msg;
    message.success(msg);
    role_list();
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 谈话窗是否展示
const open_add = ref<boolean>(false);
const labelCol = { span: 5 };
const wrapperCol = { span: 13 };
const formRef = ref();
// 接口--修改和添加用一样的接口
interface FormState {
  name: string;
  description: string;
  rolecode: string;
}
// 表单元素
const formState: UnwrapRef<FormState> = reactive({
  name: "",
  description: "",
  rolecode: "",
});
// 规则--修改和添加用一样的接口
const rules: Record<string, Rule[]> = {
  name: [
    { required: true, message: "请输入角色名字", trigger: "change" },
    { min: 2, max: 10, message: "长度为2到10个字符串", trigger: "blur" },
  ],
  description: [
    { required: true, message: "请输入角色描述", trigger: "change" },
    { min: 3, message: "长度最少为3个字符串", trigger: "blur" },
  ],
  rolecode: [
    { required: true, message: "请输入角色编码", trigger: "change" },
    { min: 2, max: 15, message: "长度为2到15个字符串", trigger: "blur" },
  ],
};
// 添加按钮
const showModal_add = () => {
  open_add.value = true;
};
// 对话窗中的确定按钮
const handleOk = () => {
  formRef.value
    .validate()
    .then(() => {
      console.log("values", formState, toRaw(formState));
      open_add.value = false;
      // 添加角色的接口
      add_role();
    })
    .catch((error) => {
      console.log("error", error);
    });
};
// 3. 表格中的一系列操作及数据
type Key = string | number;
const loading = ref<boolean>(false)
// 表头
const columns = [
  {
    title: "角色名称",
    dataIndex: "name",
    key: "name",
    width: 100,
  },
  {
    title: "角色编码",
    dataIndex: "rolecode",
    key: "rolecode",
    width: 150,
  },
  {
    title: "描述",
    dataIndex: "description",
    key: "description",
    width: 200,
  },
  {
    title: "创建时间",
    dataIndex: "createtime",
    key: "createtime",
    width: 120,
  },
  {
    title: "操作",
    key: "action",
    width: 150,
  },
];
// 表中数据
const dataSource = ref<string[]>([]);
// 勾选框的一系列操作
const state = reactive<{
  selectedRowKeys: Key[];
  loading: boolean;
  pageSize: number;
  total: number;
  current: number;
}>({
  selectedRowKeys: [],
  loading: false,
  pageSize: 10,
  total: 100,
  current: 1,
});
// 勾选时候的事件
const onSelectChange = (selectedRowKeys: Key[]) => {
  console.log("selectedRowKeys changed: ", selectedRowKeys);
  state.selectedRowKeys = selectedRowKeys;
};
// 请求后端列表接口
const role_list = async () => {
  try {
    loading.value = true; // 开始加载
    const response = await http.get("/api/roles/list", {
      params: {
        name: role_name.value.trim(),
        rolecode: role_code.value.trim(),
        page_size: state.pageSize,
        page: state.current,
      },
    });
    // console.log(response.data.data)
    const roles = response.data.data.roles;
    // 为每个角色对象添加一个唯一的 key 值，这里使用角色的 id 作为 key
    dataSource.value = roles.map((role, index) => {
      const localTime = new Date(Number(role.createtime));
      return {
        ...role,
        createtime: dayjs(localTime).format('YYYY-MM-DD HH:mm:ss'), // 使用转换后的本地时间字符串
        key: role.id, // 确保每个对象都有一个唯一的 key 值
      };
    });
    state.total = response.data.data.total[0].count;
  } catch (error) {
    console.log("请求失败：：", error);
  }finally{
    loading.value = false; // 开始加载
  }
};
// 4. 修改角色一系列操作
// 修改角色--保存数据
const edit_id = ref<number>(); // 修改的id
// 表单元素
const formState_edit: UnwrapRef<FormState> = reactive({
  name: "",
  description: "",
  rolecode: "",
});
const edit_save = async () => {
  try {
    const response = await http.post("/api/roles/edit_set", {
      id: edit_id.value,
      name: formState_edit.name,
      description: formState_edit.description,
      rolecode: formState_edit.rolecode,
    });
    role_list();
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 弹窗的关闭与否
const open_edit = ref<boolean>(false);
const formRef_edit = ref();
// 查看角色权限详情
const per_view = async (id: number) => {
  try {
    const response = await http.get("/api/roles/per_view", {
      params: {
        id: id,
      },
    });
    console.log(response);
    const msg = response.data.msg;
    if (response.data.code === 1) {
      message.error(msg);
    } else {
      visible.value = true;
      // message.success(msg);
      roleData.value = response.data.results;
    }
    // 删除成功时候调用列表
    role_list();
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 打开谈话窗的按钮方法// 修改角色--获取数据
const showModal_edit = async (id: number) => {
  // console.log(id)
  open_edit.value = true;
  try {
    const response = await http.get("/api/roles/edit_get", {
      params: {
        id: id,
      },
    });
    formState_edit.name = response.data.results[0].name;
    formState_edit.description = response.data.results[0].description;
    formState_edit.rolecode = response.data.results[0].rolecode;
    edit_id.value = response.data.results[0].id;
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 谈话框中点击确定的时候方法
const handleOk_edit = () => {
  formRef_edit.value
    .validate()
    .then(() => {
      console.log("values", formState_edit, toRaw(formState_edit));
      open_edit.value = false;
      // 修改角色--保存数据
      edit_save();
    })
    .catch((error) => {
      console.log("error", error);
    });
};
// 5. 删除角色-软删除
const del_user_f = (id: number) => {
  // 删除角色的对话框
  Modal.confirm({
    title: "禁用角色",
    icon: createVNode(ExclamationCircleOutlined),
    content: "您确定要禁用此角色吗？",
    okText: "确定",
    okType: "danger",
    cancelText: "取消",
    async onOk() {
      console.log("OK");
      // 删除的接口
      try {
        const response = await http.get("/api/roles/del_f", {
          params: {
            id: id,
          },
        });
        console.log(response);
        const msg = response.data.msg;
        message.success(msg);
        // 删除成功时候调用列表
        role_list();
      } catch (error) {
        console.log("请求失败：：", error);
      }
    },
    onCancel() {
      console.log("Cancel");
    },
  });
};
const start_user_f = async (id: number) => {
  try {
    const response = await http.get("/api/roles/start", {
      params: {
        id: id,
      },
    });
    console.log(response);
    const msg = response.data.msg;
    message.success(msg);
    // 删除成功时候调用列表
    role_list();
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 6. 删除角色-真删除
const del_user_t = (id: number) => {
  // 删除角色的对话框
  Modal.confirm({
    title: "删除角色",
    icon: createVNode(ExclamationCircleOutlined),
    content: "您确定要删除此角色吗？",
    okText: "确定",
    okType: "danger",
    cancelText: "取消",
    async onOk() {
      console.log("OK");
      // 删除的接口
      try {
        const response = await http.get("/api/role/del_t", {
          params: {
            id: id,
          },
        });
        console.log(response);
        const msg = response.data.msg;
        message.success(msg);
        // 删除成功时候调用列表
        role_list();
      } catch (error) {
        console.log("请求失败：：", error);
      }
    },
    onCancel() {
      console.log("Cancel");
    },
  });
};
// 7. 对话框--角色权限设置
const open_set = ref<boolean>(false);
const value_set = ref<number[]>([]);
const set_permis_id = ref<number>();
const set_permis_name = ref<string>();
const set_permis_title = ref<string>();
// 权限设置按钮
const permise_set = (record: any) => {
  open_set.value = true;
  set_permis_id.value = record.id;
  set_permis_name.value = record.name;
  console.log(set_permis_name.value);
  set_permis_title.value = `角色:"${record.name}"的权限设置`;
  getUserPermissions();
};

// 权限ids
const permise_ids = ref<string>("");
// 对话框中的确定按钮
const handleOk_set = async () => {
  if (value_set.value.length === 0) {
    // 如果 value_set 为空，则阻止提交
    message.warning("请至少选择一种权限");
    return;
  }
  // 如果 value_set 不为空，则可以提交
  open_set.value = false;

  console.log(value_set.value);
  // 将所有选中的 id 转换为字符串并存放在 permise_ids 中
  permise_ids.value = value_set.value.map((item) => item).join(",");

  console.log("permise_ids", permise_ids.value);
  // 这里可以添加提交逻辑
  try {
    const response = await http.get("/api/roles/set_permission", {
      params: {
        id: set_permis_id.value,
        expression_ids: permise_ids.value,
      },
    });
    console.log("设置权限的接口", response);
    value_set.value = [];
  } catch (error) {
    console.log("请求失败：：", error);
    message.success("请求失败");
  }
  // set_permis();
};
const options = ref<CascaderProps["options"][]>([]);
// 接口-获取全部权限
const all_permis = async () => {
  try {
    const response = await http.get("/api/permissions/all");
    console.log(response.data.results);
    const results = response.data.results;
    // 处理数据
    // 1. 创建映射，存储节点
    const nodesMap = new Map();
    results.forEach((item: any) => {
      nodesMap.set(item.id, { label: item.name, value: item.id, children: [] });
    });

    // 2. 构建树形结构
    const tree = [];
    results.forEach((item: any) => {
      const node = nodesMap.get(item.id);
      if (item.father === 0) {
        // 根节点直接添加到树中
        tree.push(node);
      } else {
        // 非根节点添加到其父节点的 children 中
        const parent = nodesMap.get(item.father);
        if (parent) {
          parent.children.push(node);
        }
      }
    });
    // 打印转换后的树形结构
    console.log(tree);
    options.value = tree;
  } catch (error) {
    console.log("请求失败：：", error);
  }
};
// 获取当前点击的角色拥有的权限
const getUserPermissions = async () => {
  try {
    const results = await http.get("/api/permissions/getrole_permissions", {
      params: {
        role_id: set_permis_id.value,
      },
    });
    console.log("获取当前点击的角色拥有的权限成功：", results);
    const userPermission_ids = results.data.results.map((item: any) => {
      return item.permiss_id;
    });
    value_set.value = userPermission_ids;
  } catch (error) {
    console.log("获取当前角色拥有的权限失败：", error);
  }
};
// 生命周期钩子函数
onMounted(() => {
  role_list();
  // 全部权限接口
  all_permis();
});
</script>

<style scoped>
:deep(:where(.css-dev-only-do-not-override-1p3hq3p).ant-btn > .anticon + span),
:deep(:where(.css-dev-only-do-not-override-1p3hq3p).ant-btn > span + .anticon) {
  margin-inline-start: 0px;
}
</style>